﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using Kooboo.HtmlFunc;
using Kooboo.HtmlFunc.Providers;

namespace Kooboo.CMS.SiteConverter.Parser.Razor
{
    public class MenuParser : ParserBase, IParser<IMenu>
    {
        public static readonly string defaultMenuConStart = Environment.NewLine + "    <ul class=\"menu\">";
        public static readonly string defaultMenuConEnd = Environment.NewLine + "    </ul>";
        public static readonly string defaultMenuItemFormat = "<li class=\"{0}\">{1}</li>";
        public static readonly string defaultCurrentStyleName = "current";

        public static void Format(IMenu obj, string loopStart, string loopEnd, string classFormat,
            string linkFormat, string linkHref, string linkText)
        {
            if (obj.StartNode == null)
            {
                return;
            }

            var defaultClassFormat = string.Format(classFormat, defaultCurrentStyleName);

            if (obj.ItemStartNode != null)
            {
                NodeExtension.RemoveItemSiblings(obj);

                if (obj.CurrentClassAttribute != null)
                {
                    var currentStyleName = obj.CurrentClassAttribute.Value;
                    var currentStyleNode = obj.CurrentClassAttribute.OwnerNode;
                    currentStyleName = string.IsNullOrWhiteSpace(currentStyleName) ? defaultCurrentStyleName : currentStyleName;
                    currentStyleNode.RemoveClass(currentStyleName);
                    currentStyleNode.AddClass(string.Format(classFormat, currentStyleName));
                }

                if (obj.LinkStartNode != null)
                {
                    ProcessLink(obj, defaultClassFormat, linkFormat, linkHref, linkText);
                }
                else
                {
                    var inner = NodeExtension.CreateNode(string.Format(defaultMenuItemFormat, defaultClassFormat, linkFormat));
                    NodeExtension.ReplaceInner(obj.ItemStartNode, obj.ItemEndNode, inner);
                }

                if (obj.ItemStartNode.ParentNode == obj.StartNode.ParentNode)
                {
                    obj.ItemStartNode.ParentNode.InsertBefore(NodeExtension.CreateNode(defaultMenuConStart + loopStart), obj.ItemStartNode);
                    obj.ItemEndNode.ParentNode.InsertAfter(NodeExtension.CreateNode(loopEnd + defaultMenuConEnd), obj.ItemEndNode);
                }
                else
                {
                    obj.ItemStartNode.ParentNode.InsertBefore(NodeExtension.CreateNode(loopStart), obj.ItemStartNode);
                    obj.ItemEndNode.ParentNode.InsertAfter(NodeExtension.CreateNode(loopEnd), obj.ItemEndNode);
                }
            }
            else
            {
                if (obj.LinkStartNode != null)
                {
                    ProcessLink(obj, defaultClassFormat, linkFormat, linkHref, linkText);
                }
                else
                {
                    var inner = NodeExtension.CreateNode(string.Format(defaultMenuItemFormat, defaultClassFormat, linkFormat));
                    NodeExtension.ReplaceInner(obj.StartNode, obj.EndNode, inner);
                }

                obj.StartNode.ParentNode.InsertAfter(NodeExtension.CreateNode(defaultMenuConStart + loopStart), obj.StartNode);
                obj.EndNode.ParentNode.InsertBefore(NodeExtension.CreateNode(loopEnd + defaultMenuConEnd), obj.EndNode);
            }

            if (ParserSetting.RemoveFuncMarkers)
            {
                if (obj.LinkTextStartNode != null)
                {
                    obj.LinkTextEndNode.RemovePrevWhitespace();
                    obj.LinkTextEndNode.RemoveNextWhitespace();
                    obj.LinkTextEndNode.ParentNode.RemoveChild(obj.LinkTextEndNode);
                    obj.LinkTextStartNode.RemovePrevWhitespace();
                    obj.LinkTextStartNode.RemoveNextWhitespace();
                    obj.LinkTextStartNode.ParentNode.RemoveChild(obj.LinkTextStartNode);
                }

                if (obj.CurrentClassAttribute != null)
                {
                    obj.CurrentClassAttribute.Remove();
                }

                if (obj.LinkStartNode != null)
                {
                    obj.LinkEndNode.RemoveWithPrevWhitespace();
                    obj.LinkStartNode.RemoveWithPrevWhitespace();
                }

                if (obj.ItemStartNode != null)
                {
                    obj.ItemEndNode.RemoveWithPrevWhitespace();
                    obj.ItemStartNode.ParentNode.RemoveChild(obj.ItemStartNode);
                }

                if (obj.StartNode != null)
                {
                    obj.EndNode.RemoveWithPrevWhitespace();
                    obj.StartNode.ParentNode.RemoveChild(obj.StartNode);
                }
            }
        }

        private static void ProcessLink(IMenu obj, string classFormat, string linkFormat, string linkHref, string linkText)
        {
            var element = obj.LinkStartNode.NextSibling;
            while (element != null && element != obj.LinkEndNode && !element.Is("A"))
                element = element.NextSibling;

            if (element != null && element.Is("A"))
            {
                if (obj.LinkTextStartNode != null)
                {
                    NodeExtension.ReplaceInner(obj.LinkTextStartNode, obj.LinkTextEndNode, linkText);
                }
                else
                {
                    element.InnerHtml = linkText;
                }

                //if (obj.CurrentClassAttribute == null)
                //{
                //    element.AddClass(classFormat);
                //}

                element.Attr("href", linkHref);
            }
            else
            {
                var inner = string.Empty;
                if (obj.LinkStartNode.ParentNode == obj.StartNode.ParentNode)
                {
                    inner = string.Format(defaultMenuItemFormat, classFormat, linkFormat);
                }
                else
                {
                    inner = linkFormat;
                    obj.LinkStartNode.ParentNode.AddClass(classFormat);
                }
                NodeExtension.ReplaceInner(obj.LinkStartNode, obj.LinkEndNode, inner);
            }
        }

        #region IParser<IMenu> Members

        public void Parse(IMenu obj)
        {
            var loopStart = @"
    @foreach (var item in MenuHelper.Top())
    {
        if (item.Navigation.Show)
        {";
            var classFormat = "@(MenuHelper.IsCurrent(item) ? \"{0}\" : \"\")";
            var linkFormat = "@Html.FrontHtml().PageLink(item.LinkText, item.FullName)";
            var linkHref = @"@Url.FrontUrl().PageUrl(item.FullName)";
            var linkText = @"@item.LinkText";
            var loopEnd = @"
        }
    }";
            Format(obj, loopStart, loopEnd, classFormat, linkFormat, linkHref, linkText);
        }

        #endregion
    }
}
